package com.bankcomm.util;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import com.rytong.tools.utils.LPToastUtil;
import com.rytong.tools.utils.Utils;

public class BranchBankUtils {
	// 检测字符串中是否包含单个未付值encrypt属性，如果包含则将该属性补充完整
	public static String includeAloneAttribute(String str) {
		LPToastUtil.getInstance().isHasStyle = false;
		if (null == str || "".equalsIgnoreCase(str)){
			return str;
		}
		if(str.contains("<style>") && str.contains("script")){
			LPToastUtil.getInstance().isHasStyle = true;
			return str;			
		}
		
		str = str.replaceAll("<font", "<label");
		str = str.replaceAll("</font>", "</label>");
		str = str.replaceAll("<h1>", "<label>");
		str = str.replaceAll("<h2>", "<label>");
		str = str.replaceAll("<h3>", "<label>");
		str = str.replaceAll("<h4>", "<label>");
		str = str.replaceAll("<h5>", "<label>");
		str = str.replaceAll("<h6>", "<label>");

		str = str.replaceAll("</h1>", "</label>");
		str = str.replaceAll("</h2>", "</label>");
		str = str.replaceAll("</h3>", "</label>");
		str = str.replaceAll("</h4>", "</label>");
		str = str.replaceAll("</h5>", "</label>");
		str = str.replaceAll("</h6>", "</label>");
		str = str.replace("&nbsp;", " ");

		String[] strArrayTemp = { "encrypt", "selected", "checked" };
		// encryptMode = oneSecret
		String[] insertStr = { "= '01'", "= 'true'", "='ture'" };
		String xmlTemp = str;
		String xml = "";

		int split = 3;
		for (int i = 0; i < strArrayTemp.length; i++) {
			while ((xmlTemp.indexOf(strArrayTemp[i])) != -1) {
				int index = xmlTemp.indexOf(strArrayTemp[i]);
				int length = strArrayTemp[i].length();
				String strChar = xmlTemp.substring((index + length), (index
						+ length + 1));
				if (strChar.equals("=")) {
					xml = xml.concat(xmlTemp.substring(0, index + length
							+ split));
					index += (length + split);
					xmlTemp = xmlTemp.substring(index);
				} else {
					String strRep = strArrayTemp[i];
					if (strArrayTemp[i].equals("encrypt")) {
						strRep = "encryptMode";
					}
					xml = xml.concat(xmlTemp.substring(0, index))
							.concat(" " + strRep).concat(insertStr[i]);
					index += length;
					xmlTemp = xmlTemp.substring(index);
				}
			}
			xmlTemp = xml.concat(xmlTemp);
			xml = "";
		}
		return xmlTemp;
	}

	/**
	 * 在<body>或者<form>子节点添加<br/>
	 * 标签
	 * 
	 * @param xml
	 *            元报文
	 * @return
	 */
	public static String addBrAtEnd(String xml) {
		if(null == xml || "".equalsIgnoreCase(xml)){
			return xml;
		}
		
		if(LPToastUtil.getInstance().isHasStyle){
			return xml;			
		}
		
		Utils.printOutToConsole("原报文: " + xml);
		//对分行报文进行预处理
		xml = preBrankBankXml(xml);
		
		StringBuilder result = new StringBuilder();
		try {
			// 初始化噗儿解析器
			XmlPullParserFactory xmlFactory = XmlPullParserFactory
					.newInstance();
			xmlFactory.setNamespaceAware(true);
			XmlPullParser parser = xmlFactory.newPullParser();
			parser.setInput(new StringReader(xml));

			final String br = "<br/>";
			String endTag = "";
			String insertString = null;
			// 触发事件
			int event = parser.getEventType();
			// 父标签
			String parentTag = null;
			// 当前标签
			String currentTag = null;
			// 上次遍历到的点
			int lastPosition = 0;
			// 当前遍历到的点
			int parserPosition = 0;
			// 标签's 堆栈
			Stack<String> tagStack = new Stack<String>();

			// 判断是是否是空标签：如<element />返回true,如<element></element>返回false
			boolean isEmptyElementTag = false;
			while (event != XmlPullParser.END_DOCUMENT) {
				switch (event) {
				case XmlPullParser.START_TAG:
					Utils.printOutToConsole("START_TAG:" + currentTag);
					// 入栈
					tagStack.push(parser.getName());
					isEmptyElementTag = false;
					isEmptyElementTag = parser.isEmptyElementTag();
					break;
				case XmlPullParser.END_TAG:
					// 出栈
					tagStack.pop();
					currentTag = parser.getName();
					Utils.printOutToConsole("END_TAG:" + currentTag);
					// 父标签是 <form> <body>, 则加换行
					if (tagStack.isEmpty()) {
						parentTag = null;
					} else {
						parentTag = tagStack.peek();
					}

					if ("form".equals(currentTag)) {
						endTag = ">";
					} else if (currentTag.equals("input") && isEmptyElementTag) {
						endTag = "/>";
					} else {
						endTag = "</" + currentTag + ">";
					}

					int pos1 = xml.indexOf(endTag, lastPosition);
					int pos2 = xml.indexOf("/>", lastPosition);

					if (pos1 != -1 && pos2 != -1) {
						parserPosition = Math.min(pos1, pos2);
						if (pos1 > pos2) {
							endTag = "/>";
						}
					} else {
						parserPosition = Math.max(pos1, pos2);
						if (pos1 == -1) {
							endTag = "/>";
						}
					}

					if ("br".equals(currentTag)) {
						if (("body".equals(parentTag) || "form".equals(parentTag))) {
							// 略过<br/>
							pos2 += endTag.length();
							parserPosition = pos2;
							lastPosition = pos2;
							endTag = " ";
						} else {
							endTag = br;
							parserPosition = lastPosition;
						}
					}

					if (parserPosition == -1) {
						throw new Exception("报文解析到标签</" + currentTag + ">时发生错误!");
					}
					
					parserPosition += endTag.length();
					insertString = xml.substring(lastPosition, parserPosition);

					result.append(insertString);
                    if((null != parentTag && parentTag.equals("div") && currentTag.equals("label")) || "table".equals(currentTag) || "div".equals(currentTag) || (("body".equals(parentTag) || "form".equals(parentTag)) && 
                            ((!"br".equals(currentTag)) && (!"style".equals(currentTag)) && (!"head".equals(currentTag)) && (!"form".equals(currentTag))))) {
                        result.append(br);
                    }
					lastPosition = parserPosition;
					break;
				case XmlPullParser.TEXT:
					//Utils.printOutToConsole("text:" + parser.getName());
					break;
				}
				event = parser.next();
			}
			result.append(xml.substring(lastPosition));
		} catch (Exception e) {
			e.printStackTrace();
		}
		Utils.printOutToConsole("结果报文: " + result.toString());
		return result.toString();
	}

	/**
	 * 对分行中的报文预处理，以兼容二代手机银行
	 * @param xml
	 * @return
	 */
	private static String preBrankBankXml(String xml){
		if(null == xml || "".equalsIgnoreCase(xml)){
			return xml;
		}
		
		/*try {
			xml = BranchBankUtils.format(xml);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
		
		//替换br换行符
		xml = xml.replaceAll("<br />", "<br/>");
		if(!xml.contains("<style>") && !xml.contains("script")){
			xml = xml.replaceAll("<br/>", "");			
		}
		if (xml != null && xml.indexOf("<!--") != -1) {
			xml = removeNote(xml);
		}
		
		//替换分行中错误的标签，广东分行中
		xml = xml.replace("<lable>", "<label>");
		xml = xml.replace("</lable>", "</label>");
		
		//处理P标签里面的文字
		xml = insertLabelTagInPTag(xml);
		return xml;
	}
	

	/**
	 * 分行特色中，在<body>或者<form>子节点添加<br/>
	 * 标签前，需要去除注释，否则后续将会解析错误
	 * 
	 * @param xml
	 *            原报文
	 * @return
	 */
	public static String removeNote(String reply) {
		StringBuilder result = new StringBuilder();
		String temp = reply;
		while (temp.indexOf("<!--") != -1) {
			result = new StringBuilder();
			int index = temp.indexOf("<!--");
			int index1 = temp.indexOf("-->");
			if (index > -1) {
				result.append(temp.substring(0, index));
				result.append(temp.substring(index1 + 3));
			}
			temp = result.toString();
		}
		result = null;
		return temp;
	}

	/**
	 * 利用dom4j，对分行报文预先格式化处理，然后再进行下面的解析
	 * @param str
	 * @return
	 * @throws Exception
	 */
/*	public static String format(String str)	throws Exception {
		SAXReader reader = new SAXReader();
		// System.out.println(reader);
		// 注释：创建一个串的字符输入流
		StringReader in = new StringReader(str);
		Document doc = reader.read(in);
		// System.out.println(doc.getRootElement());
		// 注释：创建输出格式
		OutputFormat formater = OutputFormat.createPrettyPrint();
		//formater=OutputFormat.createCompactFormat();
		// 注释：设置xml的输出编码
		formater.setEncoding("utf-8");
		// 注释：创建输出(目标)
		StringWriter out = new StringWriter();
		// 注释：创建输出流
		XMLWriter writer = new XMLWriter(out, formater);
		// 注释：输出格式化的串到目标中，执行后。格式化后的串保存在out中。
		writer.write(doc);

		writer.close();
		Utils.printOutToConsole("格式化后报文："+out.toString());
		// 注释：返回我们格式化后的结果
		return out.toString();
	}*/

	/**
	 * 查找p标签，并且改造
	 * 
	 * @param xml
	 * @return
	 */
	public static String findPTagAndChange(String xml) {
		if (null != xml && !"".equalsIgnoreCase(xml)) {
			int idxStart = xml.indexOf("<p>");
			boolean hasPTag = false;
			if (idxStart != -1) {
				hasPTag = true;
				// <p>标签前面的字符串
				String preXmlStr = xml.substring(0, idxStart);
				// <p>标签后面的字符串
				String endXmlStr = xml.substring(idxStart);
				while (hasPTag) {
					idxStart = endXmlStr.indexOf("<p>");
					int idxEnd = endXmlStr.indexOf("</p>");

					String pContent = endXmlStr.substring(idxStart, idxEnd + 4);
					String changePContent = insertLabelTagInPTag(pContent);
					preXmlStr = preXmlStr + changePContent;

					endXmlStr = endXmlStr.substring(idxEnd + 4);
					if (endXmlStr.indexOf("<p>") == -1) {
						hasPTag = false;
					}
				}
				return (preXmlStr + endXmlStr);
			}
		}
		return xml;
	}

	/**
	 * 改造p标签
	 * 
	 * 查找p标签没有节点的文字，并插入label标签替换
	 * 
	 * @param pContent
	 * @return xml
	 */
	public static String insertLabelTagInPTag(String pContent) {
		if(null == pContent || "".equalsIgnoreCase(pContent) || pContent.indexOf("<p>") == -1){
			return pContent;
		}
		
		try {
			List<String> pts = new ArrayList<String>();
			// 初始化噗儿解析器
			XmlPullParserFactory xmlFactory = XmlPullParserFactory
					.newInstance();
			xmlFactory.setNamespaceAware(true);
			XmlPullParser parser = xmlFactory.newPullParser();
			parser.setInput(new StringReader(pContent));

			String parentTag = null;
			// 触发事件
			int event = parser.getEventType();
			Stack<String> tagStack = new Stack<String>();
			while (event != XmlPullParser.END_DOCUMENT) {
				switch (event) {
				case XmlPullParser.START_TAG:
					tagStack.push(parser.getName());
					break;
				case XmlPullParser.END_TAG:
					tagStack.pop();
					break;
				case XmlPullParser.TEXT:
					String text = parser.getText();

					if (tagStack.isEmpty()) {
						parentTag = null;
					} else {
						parentTag = tagStack.peek();
					}

					// 查找到p标签的文字内容，并保存起来
					if (null != text && !"".equalsIgnoreCase(text.trim()) && null != parentTag && parentTag.equalsIgnoreCase("p")) {
	            		if(!pts.contains(text.trim())){
	            			pts.add(text.trim());	            			
	            		}
					}
					break;
				}
				event = parser.next();
			}

			// 开始处理p标签的文字，在两边加上label
			if (pts.size() > 0) {
				for (int i = 0; i < pts.size(); i++) {
					String middle = pts.get(i);
					pContent = pContent.replaceAll(middle, "<br /><label>" + middle + "</label><br />");
				}
			}

			pts.clear();
			pts = null;
			tagStack.clear();
			tagStack = null;
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 将p标签替换为div
		pContent = pContent.replaceAll("<p>", "<div>");
		pContent = pContent.replaceAll("</p>", "</div>");
		return pContent;
	}
}
